/*
 * myqueue.c -- implementation for queue ops
 */

#include "myqueue.h"
#include <malloc.h>
#include <stdio.h>

void mythread_q_init(mythread_queue_t *headp, void *item)
{
	mythread_queue_t new, head;
	
	new = (mythread_queue_t) malloc(sizeof(struct mythread_queue));

	if (new == NULL) {
		printf("malloc error\n");
		exit(1);
	}

	new->item = item;
	
	new->prev = new;
	new->next = new;
	
	*headp = new;
}

void mythread_enq_tail(mythread_queue_t *headp, void *item)
{
	mythread_queue_t new, head;
	
	if (*headp == NULL) {
		mythread_q_init(headp, item);
		return;
	}
	
	head = *headp;
	
	new = (mythread_queue_t) malloc(sizeof(struct mythread_queue));

	if (new == NULL) {
		printf("malloc error\n");
		exit(1);
	}
	
	new->item = item;
	
	new->prev = head->prev;
	new->next = head;
	head->prev->next = new;
	head->prev = new;
}

void mythread_enq_head(mythread_queue_t *headp, void *item)
{
	mythread_queue_t new, head;
	
	if (*headp == NULL) {
		mythread_q_init(headp, item);
		return;
	}
	
	head = *headp;
	
	mythread_enq_tail(&head->next, item);
	
	*headp = head->prev;
}


void mythread_deq(mythread_queue_t *headp, void *item)
{
	mythread_queue_t old, q, head;
	
	head = *headp;
	
	q = head;
	do {
		if (q->item == item) {
			old = q;
			old->next->prev = q->prev;
			old->prev->next = q->next;

			if (old == head) {
				*headp = (old->next == old) ? NULL : old->next;
			}

			free(old);
			return;
		}

		q = q->next;
	} while (q != head);
}
